@@ -464,7 +464,7 @@ class UserInfo(BaseModelMixin, LensmanTypeBoolMixin):  | 
            ||
| 464 | 464 | 
                def sendcustomwxamessage(self):  | 
            
| 465 | 465 | 
                # 关注公众号 + 未领保修卡 + 已绑定镜头  | 
            
| 466 | 466 | 
                return self.subscribe and not self.has_membercard and self.shots_num  | 
            
| 467 | 
                -  | 
            |
| 467 | 
                +  | 
            |
| 468 | 468 | 
                @property  | 
            
| 469 | 469 | 
                def admindata(self):  | 
            
| 470 | 470 | 
                         return {
               | 
            
                @@ -481,7 +481,7 @@ class UserInfo(BaseModelMixin, LensmanTypeBoolMixin):  | 
            ||
| 481 | 481 | 
                'memberusercardcode': self.memberusercardcode,  | 
            
| 482 | 482 | 
                'created_at': tc.local_string(self.created_at, format='%Y-%m-%d'),  | 
            
| 483 | 483 | 
                 | 
            
| 484 | 
                - #会员信息  | 
            |
| 484 | 
                + # 会员信息  | 
            |
| 485 | 485 | 
                'integral': self.integral,  | 
            
| 486 | 486 | 
                'shots_num': self.shots_num,  | 
            
| 487 | 487 | 
                'level': self.level,  | 
            
                @@ -8,15 +8,13 @@ from django_logit import logit  | 
            ||
| 8 | 8 | 
                from django_response import response  | 
            
| 9 | 9 | 
                from paginator import pagination  | 
            
| 10 | 10 | 
                from TimeConvert import TimeConvert as tc  | 
            
| 11 | 
                -from django.utils import timezone  | 
            |
| 12 | 11 | 
                from django.db.models import Sum  | 
            
| 13 | 12 | 
                 | 
            
| 14 | 13 | 
                from mch.models import AdministratorInfo, ConsumeInfoSubmitLogInfo, SaleclerkInfo  | 
            
| 15 | 14 | 
                from statistic.models import ConsumeModelSaleStatisticInfo, ConsumeSaleStatisticInfo, ConsumeUserStatisticInfo, ModelSaleStatisticInfo  | 
            
| 16 | 15 | 
                from account.models import UserInfo  | 
            
| 17 | 
                -from integral.models import SaleclerkSubmitLogInfo  | 
            |
| 18 | 16 | 
                from utils.error.errno_utils import (AdministratorStatusCode, ProductBrandStatusCode, ProductCouponStatusCode,  | 
            
| 19 | 
                - ProductMachineStatusCode)  | 
            |
| 17 | 
                + ProductMachineStatusCode, UserStatusCode)  | 
            |
| 20 | 18 | 
                 | 
            
| 21 | 19 | 
                from collections import defaultdict  | 
            
| 22 | 20 | 
                import json  | 
            
                @@ -108,6 +106,7 @@ def usecoupon(request):  | 
            ||
| 108 | 106 | 
                 | 
            
| 109 | 107 | 
                return response(200, 'Use Coupon Success', u'核销优惠券成功')  | 
            
| 110 | 108 | 
                 | 
            
| 109 | 
                +  | 
            |
| 111 | 110 | 
                @logit  | 
            
| 112 | 111 | 
                def userinfo(request):  | 
            
| 113 | 112 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
                @@ -134,6 +133,7 @@ def userinfo(request):  | 
            ||
| 134 | 133 | 
                'left': left,  | 
            
| 135 | 134 | 
                })  | 
            
| 136 | 135 | 
                 | 
            
| 136 | 
                +  | 
            |
| 137 | 137 | 
                @logit  | 
            
| 138 | 138 | 
                def query_usergoods(request):  | 
            
| 139 | 139 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
                @@ -161,6 +161,7 @@ def query_usergoods(request):  | 
            ||
| 161 | 161 | 
                'logs': logs,  | 
            
| 162 | 162 | 
                })  | 
            
| 163 | 163 | 
                 | 
            
| 164 | 
                +  | 
            |
| 164 | 165 | 
                @logit  | 
            
| 165 | 166 | 
                def query_userinfo(request):  | 
            
| 166 | 167 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
                @@ -182,6 +183,7 @@ def query_userinfo(request):  | 
            ||
| 182 | 183 | 
                'userinfos': userinfos,  | 
            
| 183 | 184 | 
                })  | 
            
| 184 | 185 | 
                 | 
            
| 186 | 
                +  | 
            |
| 185 | 187 | 
                @logit  | 
            
| 186 | 188 | 
                def userinfo_update(request):  | 
            
| 187 | 189 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
                @@ -202,7 +204,7 @@ def userinfo_update(request):  | 
            ||
| 202 | 204 | 
                user = UserInfo.objects.get(user_id=user_id, status=True)  | 
            
| 203 | 205 | 
                except UserInfo.DoesNotExist:  | 
            
| 204 | 206 | 
                return response(UserStatusCode.USER_NOT_FOUND)  | 
            
| 205 | 
                -  | 
            |
| 207 | 
                +  | 
            |
| 206 | 208 | 
                user.integral = integral  | 
            
| 207 | 209 | 
                 | 
            
| 208 | 210 | 
                user.save()  | 
            
                @@ -210,7 +212,7 @@ def userinfo_update(request):  | 
            ||
| 210 | 212 | 
                     return response(200, 'Userinfo Update Success', u'修改用户信息成功', data={})
               | 
            
| 211 | 213 | 
                 | 
            
| 212 | 214 | 
                 | 
            
| 213 | 
                -# #统计  | 
            |
| 215 | 
                +# 统计  | 
            |
| 214 | 216 | 
                def statistic_userprofile(request):  | 
            
| 215 | 217 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
| 216 | 218 | 
                     admin_id = request.POST.get('admin_id', '')
               | 
            
                @@ -230,7 +232,7 @@ def statistic_userprofile(request):  | 
            ||
| 230 | 232 | 
                logs = ConsumeModelSaleStatisticInfo.objects.filter(model_name=model_name, ymd__gte=start_time, ymd__lte=end_time)  | 
            
| 231 | 233 | 
                else:  | 
            
| 232 | 234 | 
                logs = ConsumeModelSaleStatisticInfo.objects.filter(ymd__gte=start_time, ymd__lte=end_time)  | 
            
| 233 | 
                -  | 
            |
| 235 | 
                +  | 
            |
| 234 | 236 | 
                     sexs = {0: 0, 1: 0, 2: 0}
               | 
            
| 235 | 237 | 
                     subscribes = {0: 0, 1: 0}
               | 
            
| 236 | 238 | 
                     has_membercards = {0: 0, 1: 0}
               | 
            
                @@ -253,7 +255,8 @@ def statistic_userprofile(request):  | 
            ||
| 253 | 255 | 
                'subscribe': subscribes,  | 
            
| 254 | 256 | 
                'has_membercards': has_membercards,  | 
            
| 255 | 257 | 
                })  | 
            
| 256 | 
                -  | 
            |
| 258 | 
                +  | 
            |
| 259 | 
                +  | 
            |
| 257 | 260 | 
                def statistic_daily(request):  | 
            
| 258 | 261 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
| 259 | 262 | 
                     admin_id = request.POST.get('admin_id', '')
               | 
            
                @@ -267,7 +270,7 @@ def statistic_daily(request):  | 
            ||
| 267 | 270 | 
                administrator = AdministratorInfo.objects.get(admin_id=admin_id, user_status=AdministratorInfo.ACTIVATED, status=True)  | 
            
| 268 | 271 | 
                except AdministratorInfo.DoesNotExist:  | 
            
| 269 | 272 | 
                return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND)  | 
            
| 270 | 
                -  | 
            |
| 273 | 
                +  | 
            |
| 271 | 274 | 
                sale_logs = ConsumeSaleStatisticInfo.objects.filter(ymd__gte=start_time, ymd__lte=end_time)  | 
            
| 272 | 275 | 
                user_logs = ConsumeUserStatisticInfo.objects.filter(ymd__gte=start_time, ymd__lte=end_time)  | 
            
| 273 | 276 | 
                 | 
            
                @@ -279,6 +282,7 @@ def statistic_daily(request):  | 
            ||
| 279 | 282 | 
                'user_logs': user_logs,  | 
            
| 280 | 283 | 
                })  | 
            
| 281 | 284 | 
                 | 
            
| 285 | 
                +  | 
            |
| 282 | 286 | 
                def statistic_model(request):  | 
            
| 283 | 287 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
| 284 | 288 | 
                     admin_id = request.POST.get('admin_id', '')
               | 
            
                @@ -292,7 +296,7 @@ def statistic_model(request):  | 
            ||
| 292 | 296 | 
                administrator = AdministratorInfo.objects.get(admin_id=admin_id, user_status=AdministratorInfo.ACTIVATED, status=True)  | 
            
| 293 | 297 | 
                except AdministratorInfo.DoesNotExist:  | 
            
| 294 | 298 | 
                return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND)  | 
            
| 295 | 
                -  | 
            |
| 299 | 
                +  | 
            |
| 296 | 300 | 
                     logs = ConsumeModelSaleStatisticInfo.objects.filter(ymd__gte=start_time, ymd__lte=end_time).values_list('model_name').annotate(Sum('num'))
               | 
            
| 297 | 301 | 
                 | 
            
| 298 | 302 | 
                     logs = [{'model_name': log[0], 'num': log[1]} for log in logs]
               | 
            
                @@ -300,6 +304,7 @@ def statistic_model(request):  | 
            ||
| 300 | 304 | 
                'logs': logs  | 
            
| 301 | 305 | 
                })  | 
            
| 302 | 306 | 
                 | 
            
| 307 | 
                +  | 
            |
| 303 | 308 | 
                def statistic_distributor(request):  | 
            
| 304 | 309 | 
                     brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            
| 305 | 310 | 
                     admin_id = request.POST.get('admin_id', '')
               | 
            
                @@ -320,7 +325,7 @@ def statistic_distributor(request):  | 
            ||
| 320 | 325 | 
                 | 
            
| 321 | 326 | 
                if model_name:  | 
            
| 322 | 327 | 
                logs = logs.filter(model_name=model_name)  | 
            
| 323 | 
                -  | 
            |
| 328 | 
                +  | 
            |
| 324 | 329 | 
                distributor_logs = []  | 
            
| 325 | 330 | 
                distributor_names = []  | 
            
| 326 | 331 | 
                 | 
            
                @@ -337,17 +342,17 @@ def statistic_distributor(request):  | 
            ||
| 337 | 342 | 
                else:  | 
            
| 338 | 343 | 
                i = distributor_names.index(saleclerk_info.distributor_name)  | 
            
| 339 | 344 | 
                distributor_logs[i]['num'] += 1  | 
            
| 340 | 
                -  | 
            |
| 345 | 
                +  | 
            |
| 341 | 346 | 
                daily_logs = []  | 
            
| 342 | 
                - for k, v in groupby(logs, lambda log:log['ymd']):  | 
            |
| 347 | 
                + for k, v in groupby(logs, lambda log: log['ymd']):  | 
            |
| 343 | 348 | 
                         daily_logs.append(reduce(lambda dict1, dict2: {'ymd': k, 'num': dict1['num'] + dict2['num']}, v))
               | 
            
| 344 | 
                -  | 
            |
| 349 | 
                +  | 
            |
| 345 | 350 | 
                model_logs = []  | 
            
| 346 | 
                - for k, v in groupby(sorted(logs, key=lambda log:log['model_name']), lambda log:log['model_name']):  | 
            |
| 351 | 
                + for k, v in groupby(sorted(logs, key=lambda log: log['model_name']), lambda log: log['model_name']):  | 
            |
| 347 | 352 | 
                         model_logs.append(reduce(lambda dict1, dict2: {'model_name': k, 'num': dict1['num'] + dict2['num']}, v))
               | 
            
| 348 | 353 | 
                 | 
            
| 349 | 354 | 
                     return response(200, 'Get Distributor Statistic Success', u'获取经销商统计成功', data={
               | 
            
| 350 | 355 | 
                'daily_logs': daily_logs,  | 
            
| 351 | 356 | 
                'model_logs': model_logs,  | 
            
| 352 | 357 | 
                'distributor_logs': distributor_logs  | 
            
| 353 | 
                - })  | 
            |
| 358 | 
                + })  | 
            
                @@ -204,7 +204,6 @@ def decrypt2(request):  | 
            ||
| 204 | 204 | 
                mieli = MchInfoEncryptLogInfo.objects.get(code_url=code)  | 
            
| 205 | 205 | 
                except MchInfoEncryptLogInfo.DoesNotExist:  | 
            
| 206 | 206 | 
                return response()  | 
            
| 207 | 
                -  | 
            |
| 208 | 207 | 
                 | 
            
| 209 | 208 | 
                plaintext = mieli.plaintext  | 
            
| 210 | 209 | 
                 | 
            
                @@ -6,24 +6,25 @@ from django_response import response  | 
            ||
| 6 | 6 | 
                 | 
            
| 7 | 7 | 
                from logs.models import MchSearchModelAndCameraLogInfo  | 
            
| 8 | 8 | 
                 | 
            
| 9 | 
                +  | 
            |
| 9 | 10 | 
                @logit  | 
            
| 10 | 11 | 
                def collect_camera_adaptive_log(request):  | 
            
| 11 | 
                -  brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            |
| 12 | 
                +    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            |
| 12 | 13 | 
                 | 
            
| 13 | 
                -  user_id = request.POST.get('user_id', '')
               | 
            |
| 14 | 
                -  is_search_model = int(request.POST.get('is_search_model', 0))
               | 
            |
| 15 | 
                -  is_search_camera = int(request.POST.get('is_search_camera', 0))
               | 
            |
| 16 | 
                -  is_selected_model = int(request.POST.get('is_selected_model', 0))
               | 
            |
| 17 | 
                -  is_search_model_camera = int(request.POST.get('is_search_model_camera', 0))
               | 
            |
| 18 | 
                -  is_search_camera_after_model = int(request.POST.get('is_search_camera_after_model', 0))
               | 
            |
| 14 | 
                +    user_id = request.POST.get('user_id', '')
               | 
            |
| 15 | 
                +    is_search_model = int(request.POST.get('is_search_model', 0))
               | 
            |
| 16 | 
                +    is_search_camera = int(request.POST.get('is_search_camera', 0))
               | 
            |
| 17 | 
                +    is_selected_model = int(request.POST.get('is_selected_model', 0))
               | 
            |
| 18 | 
                +    is_search_model_camera = int(request.POST.get('is_search_model_camera', 0))
               | 
            |
| 19 | 
                +    is_search_camera_after_model = int(request.POST.get('is_search_camera_after_model', 0))
               | 
            |
| 19 | 20 | 
                 | 
            
| 20 | 
                - MchSearchModelAndCameraLogInfo.objects.create(  | 
            |
| 21 | 
                - user_id=user_id,  | 
            |
| 22 | 
                - is_search_model=is_search_model,  | 
            |
| 23 | 
                - is_search_camera=is_search_camera,  | 
            |
| 24 | 
                - is_selected_model=is_selected_model,  | 
            |
| 25 | 
                - is_search_model_camera=is_search_model_camera,  | 
            |
| 26 | 
                - is_search_camera_after_model=is_search_camera_after_model,  | 
            |
| 27 | 
                - )  | 
            |
| 21 | 
                + MchSearchModelAndCameraLogInfo.objects.create(  | 
            |
| 22 | 
                + user_id=user_id,  | 
            |
| 23 | 
                + is_search_model=is_search_model,  | 
            |
| 24 | 
                + is_search_camera=is_search_camera,  | 
            |
| 25 | 
                + is_selected_model=is_selected_model,  | 
            |
| 26 | 
                + is_search_model_camera=is_search_model_camera,  | 
            |
| 27 | 
                + is_search_camera_after_model=is_search_camera_after_model,  | 
            |
| 28 | 
                + )  | 
            |
| 28 | 29 | 
                 | 
            
| 29 | 
                - return response(200, 'Collect Camera Adaptive Log Success', u'收集型号适配日志成功')  | 
            |
| 30 | 
                + return response(200, 'Collect Camera Adaptive Log Success', u'收集型号适配日志成功')  | 
            
                @@ -229,7 +229,7 @@ def good_exchange(request):  | 
            ||
| 229 | 229 | 
                })  | 
            
| 230 | 230 | 
                else:  | 
            
| 231 | 231 | 
                pass  | 
            
| 232 | 
                -  | 
            |
| 232 | 
                +  | 
            |
| 233 | 233 | 
                goods.append(good.data(user_id))  | 
            
| 234 | 234 | 
                 | 
            
| 235 | 235 | 
                     return response(200, data={
               | 
            
                @@ -0,0 +1,221 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.conf import settings  | 
            |
| 4 | 
                +from django.contrib.admin.views.decorators import staff_member_required  | 
            |
| 5 | 
                +from django.db import transaction  | 
            |
| 6 | 
                +from django_logit import logit  | 
            |
| 7 | 
                +from django_response import response  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                +from integral.models import SaleclerkIntegralIncomeExpensesInfo, SaleclerkSubmitLogInfo  | 
            |
| 10 | 
                +from mch.models import BrandInfo, DistributorInfo, ModelInfo, SaleclerkInfo  | 
            |
| 11 | 
                +from staff.models import StaffDeleteClerkSaleSubmitLogInfo  | 
            |
| 12 | 
                +from statistic.models import (DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo,  | 
            |
| 13 | 
                + SaleclerkSaleStatisticInfo, SaleStatisticInfo)  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                +def exec_del_clerk_sale_submit(pk, username):  | 
            |
| 17 | 
                + try:  | 
            |
| 18 | 
                + ssli = SaleclerkSubmitLogInfo.objects.select_for_update().get(pk=pk)  | 
            |
| 19 | 
                + except SaleclerkSubmitLogInfo.DoesNotExist:  | 
            |
| 20 | 
                + return response()  | 
            |
| 21 | 
                +  | 
            |
| 22 | 
                + if not ssli.status:  | 
            |
| 23 | 
                + return response()  | 
            |
| 24 | 
                +  | 
            |
| 25 | 
                + if ssli.is_staff_delete:  | 
            |
| 26 | 
                + return response()  | 
            |
| 27 | 
                +  | 
            |
| 28 | 
                + sn = ssli.code  | 
            |
| 29 | 
                +  | 
            |
| 30 | 
                + StaffDeleteClerkSaleSubmitLogInfo.objects.create(username=username, code=sn)  | 
            |
| 31 | 
                +  | 
            |
| 32 | 
                + ssli.status = False  | 
            |
| 33 | 
                + ssli.is_staff_delete = True  | 
            |
| 34 | 
                + ssli.save()  | 
            |
| 35 | 
                +  | 
            |
| 36 | 
                + SaleclerkIntegralIncomeExpensesInfo.objects.select_for_update().filter(code=sn).update(status=False)  | 
            |
| 37 | 
                +  | 
            |
| 38 | 
                + try:  | 
            |
| 39 | 
                + brand = BrandInfo.objects.get(pk=ssli.brand_pk)  | 
            |
| 40 | 
                + except BrandInfo.DoesNotExist:  | 
            |
| 41 | 
                + return response()  | 
            |
| 42 | 
                +  | 
            |
| 43 | 
                + try:  | 
            |
| 44 | 
                + model = ModelInfo.objects.get(pk=ssli.model_pk)  | 
            |
| 45 | 
                + except ModelInfo.DoesNotExist:  | 
            |
| 46 | 
                + return response()  | 
            |
| 47 | 
                +  | 
            |
| 48 | 
                + try:  | 
            |
| 49 | 
                + clerk = SaleclerkInfo.objects.select_for_update().get(clerk_id=ssli.clerk_id, status=True)  | 
            |
| 50 | 
                + except SaleclerkInfo.DoesNotExist:  | 
            |
| 51 | 
                + return response()  | 
            |
| 52 | 
                +  | 
            |
| 53 | 
                + try:  | 
            |
| 54 | 
                + distributor = DistributorInfo.objects.get(distributor_id=clerk.distributor_id)  | 
            |
| 55 | 
                + except DistributorInfo.DoesNotExist:  | 
            |
| 56 | 
                + return response()  | 
            |
| 57 | 
                +  | 
            |
| 58 | 
                + integral = model.integral  | 
            |
| 59 | 
                +  | 
            |
| 60 | 
                + clerk.num -= 1  | 
            |
| 61 | 
                + clerk.integral -= integral  | 
            |
| 62 | 
                + clerk.total_integral -= integral  | 
            |
| 63 | 
                + clerk.save()  | 
            |
| 64 | 
                +  | 
            |
| 65 | 
                + ymd = str(ssli.ymd)  | 
            |
| 66 | 
                +  | 
            |
| 67 | 
                + if not clerk.test_user and not ssli.dupload:  | 
            |
| 68 | 
                + # 日销量统计  | 
            |
| 69 | 
                + ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 70 | 
                + brand_id=brand.brand_id,  | 
            |
| 71 | 
                + ymd=ymd,  | 
            |
| 72 | 
                + )  | 
            |
| 73 | 
                + ssi.num -= 1  | 
            |
| 74 | 
                + ssi.save()  | 
            |
| 75 | 
                + # 月销量统计  | 
            |
| 76 | 
                + ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 77 | 
                + brand_id=brand.brand_id,  | 
            |
| 78 | 
                + ymd=ymd[:6],  | 
            |
| 79 | 
                + )  | 
            |
| 80 | 
                + ssi.num -= 1  | 
            |
| 81 | 
                + ssi.save()  | 
            |
| 82 | 
                + # 年销量统计  | 
            |
| 83 | 
                + ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 84 | 
                + brand_id=brand.brand_id,  | 
            |
| 85 | 
                + ymd=ymd[:4],  | 
            |
| 86 | 
                + )  | 
            |
| 87 | 
                + ssi.num -= 1  | 
            |
| 88 | 
                + ssi.save()  | 
            |
| 89 | 
                +  | 
            |
| 90 | 
                + # 型号销量统计  | 
            |
| 91 | 
                + mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 92 | 
                + brand_id=brand.brand_id,  | 
            |
| 93 | 
                + model_name=model.model_uni_name,  | 
            |
| 94 | 
                + ymd=ymd,  | 
            |
| 95 | 
                + )  | 
            |
| 96 | 
                + try:  | 
            |
| 97 | 
                + mssi.saleclerks.remove(clerk.clerk_id)  | 
            |
| 98 | 
                + except ValueError:  | 
            |
| 99 | 
                + pass  | 
            |
| 100 | 
                + mssi.num = len(mssi.saleclerks)  | 
            |
| 101 | 
                + mssi.save()  | 
            |
| 102 | 
                +  | 
            |
| 103 | 
                + mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 104 | 
                + brand_id=brand.brand_id,  | 
            |
| 105 | 
                + model_name=model.model_uni_name,  | 
            |
| 106 | 
                + ymd=ymd[:6],  | 
            |
| 107 | 
                + )  | 
            |
| 108 | 
                + try:  | 
            |
| 109 | 
                + mssi.saleclerks.remove(clerk.clerk_id)  | 
            |
| 110 | 
                + except ValueError:  | 
            |
| 111 | 
                + pass  | 
            |
| 112 | 
                + mssi.num = len(mssi.saleclerks)  | 
            |
| 113 | 
                + mssi.save()  | 
            |
| 114 | 
                +  | 
            |
| 115 | 
                + mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 116 | 
                + brand_id=brand.brand_id,  | 
            |
| 117 | 
                + model_name=model.model_uni_name,  | 
            |
| 118 | 
                + ymd=ymd[:4],  | 
            |
| 119 | 
                + )  | 
            |
| 120 | 
                + try:  | 
            |
| 121 | 
                + mssi.saleclerks.remove(clerk.clerk_id)  | 
            |
| 122 | 
                + except ValueError:  | 
            |
| 123 | 
                + pass  | 
            |
| 124 | 
                + mssi.num = len(mssi.saleclerks)  | 
            |
| 125 | 
                + mssi.save()  | 
            |
| 126 | 
                +  | 
            |
| 127 | 
                + # 经销商销量统计  | 
            |
| 128 | 
                + dssi, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 129 | 
                + brand_id=brand.brand_id,  | 
            |
| 130 | 
                + distributor_id=distributor.distributor_id,  | 
            |
| 131 | 
                + ymd=ymd,  | 
            |
| 132 | 
                + )  | 
            |
| 133 | 
                + dssi.distributor_name = distributor.distributor_name  | 
            |
| 134 | 
                + dssi.num -= 1  | 
            |
| 135 | 
                + dssi.save()  | 
            |
| 136 | 
                +  | 
            |
| 137 | 
                + dssi2, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 138 | 
                + brand_id=brand.brand_id,  | 
            |
| 139 | 
                + distributor_id=distributor.distributor_id,  | 
            |
| 140 | 
                + ymd=0,  | 
            |
| 141 | 
                + )  | 
            |
| 142 | 
                + dssi2.distributor_name = distributor.distributor_name  | 
            |
| 143 | 
                + dssi2.num -= 1  | 
            |
| 144 | 
                + dssi2.save()  | 
            |
| 145 | 
                +  | 
            |
| 146 | 
                + # 日省份销量统计  | 
            |
| 147 | 
                + pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 148 | 
                + brand_id=brand.brand_id,  | 
            |
| 149 | 
                + province_code=distributor.distributor_province_code,  | 
            |
| 150 | 
                + ymd=ymd,  | 
            |
| 151 | 
                + )  | 
            |
| 152 | 
                + pssi.province_name = distributor.distributor_province_name  | 
            |
| 153 | 
                + pssi.num -= 1  | 
            |
| 154 | 
                + pssi.save()  | 
            |
| 155 | 
                + # 月省份销量统计  | 
            |
| 156 | 
                + pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 157 | 
                + brand_id=brand.brand_id,  | 
            |
| 158 | 
                + province_code=distributor.distributor_province_code,  | 
            |
| 159 | 
                + ymd=ymd[:6],  | 
            |
| 160 | 
                + )  | 
            |
| 161 | 
                + pssi.province_name = distributor.distributor_province_name  | 
            |
| 162 | 
                + pssi.num -= 1  | 
            |
| 163 | 
                + pssi.save()  | 
            |
| 164 | 
                + # 年省份销量统计  | 
            |
| 165 | 
                + pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 166 | 
                + brand_id=brand.brand_id,  | 
            |
| 167 | 
                + province_code=distributor.distributor_province_code,  | 
            |
| 168 | 
                + ymd=ymd[:4],  | 
            |
| 169 | 
                + )  | 
            |
| 170 | 
                + pssi.province_name = distributor.distributor_province_name  | 
            |
| 171 | 
                + pssi.num -= 1  | 
            |
| 172 | 
                + pssi.save()  | 
            |
| 173 | 
                +  | 
            |
| 174 | 
                + # 日销售员销量统计  | 
            |
| 175 | 
                + sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 176 | 
                + brand_id=brand.brand_id,  | 
            |
| 177 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 178 | 
                + ymd=ymd,  | 
            |
| 179 | 
                + )  | 
            |
| 180 | 
                + sssi.distributor_id = distributor.distributor_id  | 
            |
| 181 | 
                + sssi.distributor_name = distributor.distributor_name  | 
            |
| 182 | 
                + sssi.distributor_short_name = distributor.distributor_short_name  | 
            |
| 183 | 
                + sssi.clerk_name = clerk.clerk_name  | 
            |
| 184 | 
                + sssi.num -= 1  | 
            |
| 185 | 
                + sssi.save()  | 
            |
| 186 | 
                + # 月销售员销量统计  | 
            |
| 187 | 
                + sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 188 | 
                + brand_id=brand.brand_id,  | 
            |
| 189 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 190 | 
                + ymd=ymd[:6],  | 
            |
| 191 | 
                + )  | 
            |
| 192 | 
                + sssi.distributor_id = distributor.distributor_id  | 
            |
| 193 | 
                + sssi.distributor_name = distributor.distributor_name  | 
            |
| 194 | 
                + sssi.distributor_short_name = distributor.distributor_short_name  | 
            |
| 195 | 
                + sssi.clerk_name = clerk.clerk_name  | 
            |
| 196 | 
                + sssi.num -= 1  | 
            |
| 197 | 
                + sssi.save()  | 
            |
| 198 | 
                + # 年销售员销量统计  | 
            |
| 199 | 
                + sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 200 | 
                + brand_id=brand.brand_id,  | 
            |
| 201 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 202 | 
                + ymd=ymd[:4],  | 
            |
| 203 | 
                + )  | 
            |
| 204 | 
                + sssi.distributor_id = distributor.distributor_id  | 
            |
| 205 | 
                + sssi.distributor_name = distributor.distributor_name  | 
            |
| 206 | 
                + sssi.distributor_short_name = distributor.distributor_short_name  | 
            |
| 207 | 
                + sssi.clerk_name = clerk.clerk_name  | 
            |
| 208 | 
                + sssi.num -= 1  | 
            |
| 209 | 
                + sssi.save()  | 
            |
| 210 | 
                +  | 
            |
| 211 | 
                +  | 
            |
| 212 | 
                +@logit  | 
            |
| 213 | 
                +@staff_member_required  | 
            |
| 214 | 
                +@transaction.atomic  | 
            |
| 215 | 
                +def del_clerk_sale_submit_api(request):  | 
            |
| 216 | 
                +    brand_id = request.GET.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
               | 
            |
| 217 | 
                +    pk = request.GET.get('pk', '')
               | 
            |
| 218 | 
                +  | 
            |
| 219 | 
                + exec_del_clerk_sale_submit(pk, request.user.username)  | 
            |
| 220 | 
                +  | 
            |
| 221 | 
                + return response(200, 'Del Success', u'删除成功')  | 
            
                @@ -6,7 +6,7 @@ from django_file_upload import views as file_views  | 
            ||
| 6 | 6 | 
                from account import tourguide_views  | 
            
| 7 | 7 | 
                from account import views as account_views  | 
            
| 8 | 8 | 
                from api import (admin_views, clerk_views, distributor_views, encrypt_views, mch_views, member_views, model_views,  | 
            
| 9 | 
                - operator_views, sr_views, log_views)  | 
            |
| 9 | 
                + operator_views, sr_views, staff_views, log_views)  | 
            |
| 10 | 10 | 
                from box import views as box_views  | 
            
| 11 | 11 | 
                from geo import views as geo_views  | 
            
| 12 | 12 | 
                from group import (groupuser_views, lensman_views, tourguidegroup_views, tourguidegroupadmin_views,  | 
            
                @@ -295,7 +295,7 @@ urlpatterns += [  | 
            ||
| 295 | 295 | 
                url(r'^admin/query_userinfo$', admin_views.query_userinfo, name='query_userinfo'),  | 
            
| 296 | 296 | 
                url(r'^admin/userinfo_update$', admin_views.userinfo_update, name='userinfo_update'),  | 
            
| 297 | 297 | 
                 | 
            
| 298 | 
                - #statistic  | 
            |
| 298 | 
                + # statistic  | 
            |
| 299 | 299 | 
                url(r'^admin/statistic/user_profile$', admin_views.statistic_userprofile, name='statistic_userprofile'),  | 
            
| 300 | 300 | 
                url(r'^admin/statistic/consumer/daily$', admin_views.statistic_daily, name='statistic_daily'),  | 
            
| 301 | 301 | 
                url(r'^admin/statistic/consumer/model$', admin_views.statistic_model, name='statistic_model'),  | 
            
                @@ -343,4 +343,8 @@ urlpatterns += [  | 
            ||
| 343 | 343 | 
                 | 
            
| 344 | 344 | 
                urlpatterns += [  | 
            
| 345 | 345 | 
                url(r'^log/camera/adaptive$', log_views.collect_camera_adaptive_log, name='log_camera_adaptive'),  | 
            
| 346 | 
                -]  | 
            |
| 346 | 
                +]  | 
            |
| 347 | 
                +  | 
            |
| 348 | 
                +urlpatterns += [  | 
            |
| 349 | 
                + url(r'^del/clerk/sale/submit$', staff_views.del_clerk_sale_submit_api, name='del_clerk_sale_submit_api'),  | 
            |
| 350 | 
                +]  | 
            
                @@ -69,12 +69,11 @@ class Command(CompatibilityBaseCommand):  | 
            ||
| 69 | 69 | 
                                     user_id = v.get('user_id', '')
               | 
            
| 70 | 70 | 
                                     ymd = v.get('ymd', '')
               | 
            
| 71 | 71 | 
                 | 
            
| 72 | 
                - #更新用户表  | 
            |
| 72 | 
                + # 更新用户表  | 
            |
| 73 | 73 | 
                user = UserInfo.objects.get(user_id=user_id, status=True)  | 
            
| 74 | 74 | 
                user.province_name = ProvinceShortModelMixin.PROVINCE_CODE_NAME_DICT.get(province_code)  | 
            
| 75 | 75 | 
                user.save()  | 
            
| 76 | 76 | 
                 | 
            
| 77 | 
                -  | 
            |
| 78 | 77 | 
                # [消费者维度]省份销量统计  | 
            
| 79 | 78 | 
                # 日  | 
            
| 80 | 79 | 
                cpssi, _ = ConsumeProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            
                @@ -3,4 +3,5 @@ from __future__ import unicode_literals  | 
            ||
| 3 | 3 | 
                 | 
            
| 4 | 4 | 
                from django.test import TestCase  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +  | 
            |
| 6 | 7 | 
                # Create your tests here.  | 
            
                @@ -3,4 +3,5 @@ from __future__ import unicode_literals  | 
            ||
| 3 | 3 | 
                 | 
            
| 4 | 4 | 
                from django.shortcuts import render  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +  | 
            |
| 6 | 7 | 
                # Create your views here.  | 
            
                @@ -20,5 +20,6 @@ class SaleclerkSubmitLogInfoAdmin(AdvancedExportExcelModelAdmin, ReadOnlyModelAd  | 
            ||
| 20 | 20 | 
                     search_fields = ('code', 'remark', 'trackingNo', 'distributor_name', 'clerk_name', 'model_name')
               | 
            
| 21 | 21 | 
                 | 
            
| 22 | 22 | 
                 | 
            
| 23 | 
                +  | 
            |
| 23 | 24 | 
                admin.site.register(SaleclerkIntegralIncomeExpensesInfo, SaleclerkIntegralIncomeExpensesInfoAdmin)  | 
            
| 24 | 25 | 
                admin.site.register(SaleclerkSubmitLogInfo, SaleclerkSubmitLogInfoAdmin)  | 
            
                @@ -0,0 +1,20 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.26 on 2020-02-25 08:28  | 
            |
| 3 | 
                +from __future__ import unicode_literals  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + dependencies = [  | 
            |
| 11 | 
                +        ('integral', '0011_auto_20191119_1348'),
               | 
            |
| 12 | 
                + ]  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                + operations = [  | 
            |
| 15 | 
                + migrations.AddField(  | 
            |
| 16 | 
                + model_name='saleclerksubmitloginfo',  | 
            |
| 17 | 
                + name='is_wxwork',  | 
            |
| 18 | 
                + field=models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u4e3a\u4f01\u4e1a\u5fae\u4fe1\u7aef', verbose_name='is_wxwork'),  | 
            |
| 19 | 
                + ),  | 
            |
| 20 | 
                + ]  | 
            
                @@ -0,0 +1,20 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.28 on 2020-03-01 12:52  | 
            |
| 3 | 
                +from __future__ import unicode_literals  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + dependencies = [  | 
            |
| 11 | 
                +        ('integral', '0012_saleclerksubmitloginfo_is_wxwork'),
               | 
            |
| 12 | 
                + ]  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                + operations = [  | 
            |
| 15 | 
                + migrations.AddField(  | 
            |
| 16 | 
                + model_name='saleclerksubmitloginfo',  | 
            |
| 17 | 
                + name='is_staff_delete',  | 
            |
| 18 | 
                + field=models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u7ba1\u7406\u5458\u5220\u9664', verbose_name='is_staff_delete'),  | 
            |
| 19 | 
                + ),  | 
            |
| 20 | 
                + ]  | 
            
                @@ -114,6 +114,8 @@ class SaleclerkSubmitLogInfo(BaseModelMixin):  | 
            ||
| 114 | 114 | 
                 | 
            
| 115 | 115 | 
                is_wxwork = models.BooleanField(_(u'is_wxwork'), default=False, help_text=_(u'是否为企业微信端'), db_index=True)  | 
            
| 116 | 116 | 
                 | 
            
| 117 | 
                + is_staff_delete = models.BooleanField(_(u'is_staff_delete'), default=False, help_text=_(u'是否管理员删除'), db_index=True)  | 
            |
| 118 | 
                +  | 
            |
| 117 | 119 | 
                class Meta:  | 
            
| 118 | 120 | 
                verbose_name = _(u'销售员扫码出库记录')  | 
            
| 119 | 121 | 
                verbose_name_plural = _(u'销售员扫码出库记录')  | 
            
                @@ -71,6 +71,7 @@ INSTALLED_APPS = (  | 
            ||
| 71 | 71 | 
                'pre',  | 
            
| 72 | 72 | 
                'sales',  | 
            
| 73 | 73 | 
                'server',  | 
            
| 74 | 
                + 'staff',  | 
            |
| 74 | 75 | 
                'statistic',  | 
            
| 75 | 76 | 
                'website',  | 
            
| 76 | 77 | 
                'daterange_filter',  | 
            
                @@ -21,15 +21,18 @@ class MchLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):  | 
            ||
| 21 | 21 | 
                     list_filter = ('operator_id', 'app_version', 'status')
               | 
            
| 22 | 22 | 
                     search_fields = ('operator_id', 'app_version')
               | 
            
| 23 | 23 | 
                 | 
            
| 24 | 
                +  | 
            |
| 24 | 25 | 
                class MchLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):  | 
            
| 25 | 26 | 
                     list_display = ('log_id', 'log_file', 'operator_id', 'app_version', 'status', 'created_at', 'updated_at')
               | 
            
| 26 | 27 | 
                     list_filter = ('operator_id', 'app_version', 'status')
               | 
            
| 27 | 28 | 
                     search_fields = ('operator_id', 'app_version')
               | 
            
| 28 | 29 | 
                 | 
            
| 30 | 
                +  | 
            |
| 29 | 31 | 
                class MchSearchModelAndCameraLogInfoAdmin(admin.ModelAdmin):  | 
            
| 30 | 32 | 
                     list_display = ('user_id', 'is_search_model', 'is_selected_model', 'is_search_camera', 'is_search_model_camera', 'is_search_camera_after_model', 'created_at')
               | 
            
| 31 | 33 | 
                     list_filter = ('is_search_model', 'is_selected_model', 'is_search_camera', 'is_search_model_camera', 'is_search_camera_after_model')
               | 
            
| 32 | 34 | 
                 | 
            
| 35 | 
                +  | 
            |
| 33 | 36 | 
                admin.site.register(MchInfoDecryptLogInfo, MchInfoDecryptLogInfoAdmin)  | 
            
| 34 | 37 | 
                admin.site.register(MchInfoEncryptLogInfo, MchInfoEncryptLogInfoAdmin)  | 
            
| 35 | 38 | 
                admin.site.register(MchSearchModelAndCameraLogInfo, MchSearchModelAndCameraLogInfoAdmin)  | 
            
                @@ -0,0 +1,35 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.26 on 2020-02-27 16:58  | 
            |
| 3 | 
                +from __future__ import unicode_literals  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +import shortuuidfield.fields  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                +class Migration(migrations.Migration):  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                + dependencies = [  | 
            |
| 12 | 
                +        ('logs', '0007_auto_20200114_1229'),
               | 
            |
| 13 | 
                + ]  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                + operations = [  | 
            |
| 16 | 
                + migrations.CreateModel(  | 
            |
| 17 | 
                + name='MchSearchModelAndCameraLogInfo',  | 
            |
| 18 | 
                + fields=[  | 
            |
| 19 | 
                +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 20 | 
                +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 21 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 22 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 23 | 
                +                ('user_id', models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='user_id')),
               | 
            |
| 24 | 
                +                ('log_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='\u65e5\u5fd7\u552f\u4e00\u6807\u8bc6', max_length=22)),
               | 
            |
| 25 | 
                +                ('is_search_model', models.IntegerField(db_index=True, default=0, help_text='\u641c\u7d22\u955c\u5934\u578b\u53f7', verbose_name='is_search_model')),
               | 
            |
| 26 | 
                +                ('is_search_camera', models.IntegerField(db_index=True, default=0, help_text='\u641c\u7d22\u76f8\u673a\u578b\u53f7', verbose_name='is_search_model')),
               | 
            |
| 27 | 
                +                ('is_search_model_camera', models.IntegerField(db_index=True, default=0, help_text='\u641c\u7d22\u76f8\u673a\u578b\u53f7\u548c\u955c\u5934\u578b\u53f7', verbose_name='is_search_model')),
               | 
            |
| 28 | 
                +                ('is_search_camera_after_model', models.IntegerField(db_index=True, default=0, help_text='\u9009\u62e9\u955c\u5934\u540e\u641c\u7d22\u76f8\u673a\u578b\u53f7', verbose_name='is_search_camera_after_model')),
               | 
            |
| 29 | 
                + ],  | 
            |
| 30 | 
                +            options={
               | 
            |
| 31 | 
                + 'verbose_name': 'mchsearchmodelandcameraloginfo',  | 
            |
| 32 | 
                + 'verbose_name_plural': 'mchsearchmodelandcameraloginfo',  | 
            |
| 33 | 
                + },  | 
            |
| 34 | 
                + ),  | 
            |
| 35 | 
                + ]  | 
            
                @@ -0,0 +1,20 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.26 on 2020-02-27 17:08  | 
            |
| 3 | 
                +from __future__ import unicode_literals  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + dependencies = [  | 
            |
| 11 | 
                +        ('logs', '0008_mchsearchmodelandcameraloginfo'),
               | 
            |
| 12 | 
                + ]  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                + operations = [  | 
            |
| 15 | 
                + migrations.AddField(  | 
            |
| 16 | 
                + model_name='mchsearchmodelandcameraloginfo',  | 
            |
| 17 | 
                + name='is_selected_model',  | 
            |
| 18 | 
                + field=models.IntegerField(db_index=True, default=0, help_text='\u641c\u7d22\u76f8\u673a\u578b\u53f7', verbose_name='is_selected_model'),  | 
            |
| 19 | 
                + ),  | 
            |
| 20 | 
                + ]  | 
            
                @@ -72,6 +72,7 @@ class MchLogInfo(BaseModelMixin):  | 
            ||
| 72 | 72 | 
                def __unicode__(self):  | 
            
| 73 | 73 | 
                return unicode(self.pk)  | 
            
| 74 | 74 | 
                 | 
            
| 75 | 
                +  | 
            |
| 75 | 76 | 
                class MchSearchModelAndCameraLogInfo(BaseModelMixin):  | 
            
| 76 | 77 | 
                user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)  | 
            
| 77 | 78 | 
                 | 
            
                @@ -88,4 +89,4 @@ class MchSearchModelAndCameraLogInfo(BaseModelMixin):  | 
            ||
| 88 | 89 | 
                verbose_name_plural = _(u'mchsearchmodelandcameraloginfo')  | 
            
| 89 | 90 | 
                 | 
            
| 90 | 91 | 
                def __unicode__(self):  | 
            
| 91 | 
                - return unicode(self.pk)  | 
            |
| 92 | 
                + return unicode(self.pk)  | 
            
                @@ -0,0 +1,20 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.26 on 2020-02-23 08:32  | 
            |
| 3 | 
                +from __future__ import unicode_literals  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + dependencies = [  | 
            |
| 11 | 
                +        ('mch', '0043_modelcamerabodyinfo'),
               | 
            |
| 12 | 
                + ]  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                + operations = [  | 
            |
| 15 | 
                + migrations.AddField(  | 
            |
| 16 | 
                + model_name='modelcamerabodyinfo',  | 
            |
| 17 | 
                + name='camera_brand_name',  | 
            |
| 18 | 
                + field=models.CharField(blank=True, help_text='\u673a\u8eab\u54c1\u724c', max_length=255, null=True, verbose_name='camera_brand_name'),  | 
            |
| 19 | 
                + ),  | 
            |
| 20 | 
                + ]  | 
            
                @@ -635,7 +635,7 @@ class ConsumeInfoSubmitLogInfo(BaseModelMixin):  | 
            ||
| 635 | 635 | 
                model_info = ModelInfo.objects.get(model_id=self.model_id)  | 
            
| 636 | 636 | 
                except ModelInfo.DoesNotExist:  | 
            
| 637 | 637 | 
                             model_info = {}
               | 
            
| 638 | 
                -  | 
            |
| 638 | 
                +  | 
            |
| 639 | 639 | 
                         return {
               | 
            
| 640 | 640 | 
                'model_name': self.model_name,  | 
            
| 641 | 641 | 
                'serialNo': self.serialNo,  | 
            
                @@ -644,6 +644,7 @@ class ConsumeInfoSubmitLogInfo(BaseModelMixin):  | 
            ||
| 644 | 644 | 
                'created_at': tc.local_string(self.created_at, format='%Y-%m-%d'),  | 
            
| 645 | 645 | 
                }  | 
            
| 646 | 646 | 
                 | 
            
| 647 | 
                +  | 
            |
| 647 | 648 | 
                class ActivityInfo(BaseModelMixin):  | 
            
| 648 | 649 | 
                FIXED_EXPIRED_TIME = 0  | 
            
| 649 | 650 | 
                CHANGED_EXPIRED_TIME = 1  | 
            
                @@ -91,7 +91,7 @@ class GoodsInfo(BaseModelMixin):  | 
            ||
| 91 | 91 | 
                'able': True,  | 
            
| 92 | 92 | 
                'value': self.value,  | 
            
| 93 | 93 | 
                }  | 
            
| 94 | 
                -  | 
            |
| 94 | 
                +  | 
            |
| 95 | 95 | 
                def details(self, user_id):  | 
            
| 96 | 96 | 
                detail = self.data(user_id)  | 
            
| 97 | 97 | 
                detail['desc'] = self.desc  | 
            
                @@ -97,9 +97,7 @@ def clerk_sale_submit_api(request):  | 
            ||
| 97 | 97 | 
                ymd = tc.local_string(format='%Y%m%d')  | 
            
| 98 | 98 | 
                 | 
            
| 99 | 99 | 
                # 是否被消费者扫过  | 
            
| 100 | 
                - has_scan = ConsumeInfoSubmitLogInfo.objects.filter(  | 
            |
| 101 | 
                - model_id=model.model_id,  | 
            |
| 102 | 
                - serialNo=serialNo).exists()  | 
            |
| 100 | 
                + has_scan = ConsumeInfoSubmitLogInfo.objects.filter(model_id=model.model_id, serialNo=serialNo).exists()  | 
            |
| 103 | 101 | 
                 | 
            
| 104 | 102 | 
                # 店员提交记录  | 
            
| 105 | 103 | 
                ssli = SaleclerkSubmitLogInfo.objects.create(  | 
            
                @@ -239,7 +237,6 @@ def clerk_sale_submit_api(request):  | 
            ||
| 239 | 237 | 
                mssi.num = len(mssi.saleclerks)  | 
            
| 240 | 238 | 
                mssi.save()  | 
            
| 241 | 239 | 
                 | 
            
| 242 | 
                -  | 
            |
| 243 | 240 | 
                # 经销商销量统计  | 
            
| 244 | 241 | 
                dssi, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            
| 245 | 242 | 
                brand_id=brand.brand_id,  | 
            
                @@ -287,15 +284,6 @@ def clerk_sale_submit_api(request):  | 
            ||
| 287 | 284 | 
                pssi.num += 1  | 
            
| 288 | 285 | 
                pssi.save()  | 
            
| 289 | 286 | 
                 | 
            
| 290 | 
                - # pssi2, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 291 | 
                - # brand_id=brand.brand_id,  | 
            |
| 292 | 
                - # province_code=distributor.distributor_province_code,  | 
            |
| 293 | 
                - # ymd=0,  | 
            |
| 294 | 
                - # )  | 
            |
| 295 | 
                - # pssi2.province_name = distributor.distributor_province_name  | 
            |
| 296 | 
                - # pssi2.num += 1  | 
            |
| 297 | 
                - # pssi2.save()  | 
            |
| 298 | 
                -  | 
            |
| 299 | 287 | 
                # 日销售员销量统计  | 
            
| 300 | 288 | 
                sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            
| 301 | 289 | 
                brand_id=brand.brand_id,  | 
            
                @@ -451,9 +439,8 @@ def clerk_checkout_serialNo_api(request):  | 
            ||
| 451 | 439 | 
                except SaleclerkInfo.DoesNotExist:  | 
            
| 452 | 440 | 
                return response(SaleclerkStatusCode.CLERK_NOT_FOUND)  | 
            
| 453 | 441 | 
                 | 
            
| 454 | 
                -  | 
            |
| 455 | 442 | 
                log = MchInfoEncryptLogInfo.objects.filter(model_pk=model_pk, sn=serialNo)  | 
            
| 456 | 
                -  | 
            |
| 443 | 
                +  | 
            |
| 457 | 444 | 
                if not log:  | 
            
| 458 | 445 | 
                return response(ProductMachineStatusCode.SN_NOT_FOUND)  | 
            
| 459 | 446 | 
                 | 
            
                @@ -37,5 +37,3 @@ def marketcodedownload(application_id, code_start, code_end, isv_application_id=  | 
            ||
| 37 | 37 | 
                code_index=code_index,  | 
            
| 38 | 38 | 
                code_url=code_url  | 
            
| 39 | 39 | 
                )  | 
            
| 40 | 
                -  | 
            |
| 41 | 
                -  | 
            
                @@ -4,14 +4,17 @@ from __future__ import division  | 
            ||
| 4 | 4 | 
                 | 
            
| 5 | 5 | 
                import xlrd  | 
            
| 6 | 6 | 
                from django.conf import settings  | 
            
| 7 | 
                +from django.db import transaction  | 
            |
| 7 | 8 | 
                from pysnippets.strsnippets import strip  | 
            
| 8 | 9 | 
                from TimeConvert import TimeConvert as tc  | 
            
| 9 | 10 | 
                 | 
            
| 10 | 
                -from mch.models import BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, ModelInfo, ModelCameraBodyInfo  | 
            |
| 11 | 
                +from integral.models import SaleclerkSubmitLogInfo  | 
            |
| 12 | 
                +from mch.models import (BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, ModelCameraBodyInfo, ModelInfo,  | 
            |
| 13 | 
                + SaleclerkInfo)  | 
            |
| 11 | 14 | 
                from statistic.models import (ConsumeDistributorSaleStatisticInfo, ConsumeModelSaleStatisticInfo,  | 
            
| 12 | 15 | 
                ConsumeProvinceSaleStatisticInfo, ConsumeSaleStatisticInfo, ConsumeUserStatisticInfo,  | 
            
| 13 | 16 | 
                DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo,  | 
            
| 14 | 
                - SaleStatisticInfo)  | 
            |
| 17 | 
                + SaleclerkSaleStatisticInfo, SaleStatisticInfo)  | 
            |
| 15 | 18 | 
                from utils.redis.connect import r  | 
            
| 16 | 19 | 
                from utils.redis.rkeys import MINI_PROGRAM_GIS_LIST  | 
            
| 17 | 20 | 
                 | 
            
                @@ -253,77 +256,246 @@ def refreshs():  | 
            ||
| 253 | 256 | 
                except ModelInfo.DoesNotExist:  | 
            
| 254 | 257 | 
                continue  | 
            
| 255 | 258 | 
                 | 
            
| 256 | 
                - cusi, _ = ConsumeUserStatisticInfo.objects.get_or_create(  | 
            |
| 257 | 
                - brand_id=mdl.brand_id,  | 
            |
| 258 | 
                - ymd=ymd,  | 
            |
| 259 | 
                - )  | 
            |
| 260 | 
                - cusi.users = list(set(cusi.users + [log.user_id]))  | 
            |
| 261 | 
                - cusi.num = len(cusi.users)  | 
            |
| 262 | 
                - cusi.save()  | 
            |
| 263 | 
                - cusi, _ = ConsumeUserStatisticInfo.objects.get_or_create(  | 
            |
| 264 | 
                - brand_id=mdl.brand_id,  | 
            |
| 265 | 
                - ymd=ymd[:6],  | 
            |
| 266 | 
                - )  | 
            |
| 267 | 
                - cusi.users = list(set(cusi.users + [log.user_id]))  | 
            |
| 268 | 
                - cusi.num = len(cusi.users)  | 
            |
| 269 | 
                - cusi.save()  | 
            |
| 270 | 
                - cusi, _ = ConsumeUserStatisticInfo.objects.get_or_create(  | 
            |
| 271 | 
                - brand_id=mdl.brand_id,  | 
            |
| 272 | 
                - ymd=ymd[:4],  | 
            |
| 273 | 
                - )  | 
            |
| 274 | 
                - cusi.users = list(set(cusi.users + [log.user_id]))  | 
            |
| 275 | 
                - cusi.num = len(cusi.users)  | 
            |
| 276 | 
                - cusi.save()  | 
            |
| 277 | 
                -  | 
            |
| 278 | 
                - cssi, _ = ConsumeSaleStatisticInfo.objects.get_or_create(  | 
            |
| 279 | 
                - brand_id=mdl.brand_id,  | 
            |
| 280 | 
                - ymd=ymd,  | 
            |
| 281 | 
                - )  | 
            |
| 282 | 
                - cssi.num += 1  | 
            |
| 283 | 
                - cssi.save()  | 
            |
| 284 | 
                - cssi, _ = ConsumeSaleStatisticInfo.objects.get_or_create(  | 
            |
| 285 | 
                - brand_id=mdl.brand_id,  | 
            |
| 286 | 
                - ymd=ymd[:6],  | 
            |
| 287 | 
                - )  | 
            |
| 288 | 
                - cssi.num += 1  | 
            |
| 289 | 
                - cssi.save()  | 
            |
| 290 | 
                - cssi, _ = ConsumeSaleStatisticInfo.objects.get_or_create(  | 
            |
| 291 | 
                - brand_id=mdl.brand_id,  | 
            |
| 292 | 
                - ymd=ymd[:4],  | 
            |
| 293 | 
                - )  | 
            |
| 294 | 
                - cssi.num += 1  | 
            |
| 295 | 
                - cssi.save()  | 
            |
| 296 | 
                -  | 
            |
| 297 | 
                - # 日型号销量统计  | 
            |
| 298 | 
                - cmssi, _ = ConsumeModelSaleStatisticInfo.objects.get_or_create(  | 
            |
| 299 | 
                - brand_id=mdl.brand_id,  | 
            |
| 300 | 
                - model_name=mdl.model_uni_name,  | 
            |
| 301 | 
                - ymd=ymd,  | 
            |
| 302 | 
                - )  | 
            |
| 303 | 
                - cmssi.num += 1  | 
            |
| 304 | 
                - cmssi.save()  | 
            |
| 305 | 
                - # 月型号销量统计  | 
            |
| 306 | 
                - cmssi, _ = ConsumeModelSaleStatisticInfo.objects.get_or_create(  | 
            |
| 307 | 
                - brand_id=mdl.brand_id,  | 
            |
| 308 | 
                - model_name=mdl.model_uni_name,  | 
            |
| 309 | 
                - ymd=ymd[:6],  | 
            |
| 310 | 
                - )  | 
            |
| 311 | 
                - cmssi.num += 1  | 
            |
| 312 | 
                - cmssi.save()  | 
            |
| 313 | 
                - # 年型号销量统计  | 
            |
| 314 | 
                - cmssi, _ = ConsumeModelSaleStatisticInfo.objects.get_or_create(  | 
            |
| 315 | 
                - brand_id=mdl.brand_id,  | 
            |
| 316 | 
                - model_name=mdl.model_uni_name,  | 
            |
| 317 | 
                - ymd=ymd[:4],  | 
            |
| 318 | 
                - )  | 
            |
| 319 | 
                - cmssi.num += 1  | 
            |
| 320 | 
                - cmssi.save()  | 
            |
| 321 | 
                -  | 
            |
| 322 | 
                -        r.rpushjson(MINI_PROGRAM_GIS_LIST, {
               | 
            |
| 323 | 
                - 'brand_id': log.brand_id,  | 
            |
| 324 | 
                - 'user_id': log.user_id,  | 
            |
| 325 | 
                - 'lat': log.lat,  | 
            |
| 326 | 
                - 'lon': log.lon,  | 
            |
| 327 | 
                - 'phone': log.phone,  | 
            |
| 328 | 
                - 'ymd': tc.local_string(tc.to_local_datetime(log.created_at), format='%Y%m%d'),  | 
            |
| 329 | 
                - })  | 
            |
| 259 | 
                + with transaction.atomic():  | 
            |
| 260 | 
                + cusi, _ = ConsumeUserStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 261 | 
                + brand_id=mdl.brand_id,  | 
            |
| 262 | 
                + ymd=ymd,  | 
            |
| 263 | 
                + )  | 
            |
| 264 | 
                + cusi.users = list(set(cusi.users + [log.user_id]))  | 
            |
| 265 | 
                + cusi.num = len(cusi.users)  | 
            |
| 266 | 
                + cusi.save()  | 
            |
| 267 | 
                + cusi, _ = ConsumeUserStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 268 | 
                + brand_id=mdl.brand_id,  | 
            |
| 269 | 
                + ymd=ymd[:6],  | 
            |
| 270 | 
                + )  | 
            |
| 271 | 
                + cusi.users = list(set(cusi.users + [log.user_id]))  | 
            |
| 272 | 
                + cusi.num = len(cusi.users)  | 
            |
| 273 | 
                + cusi.save()  | 
            |
| 274 | 
                + cusi, _ = ConsumeUserStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 275 | 
                + brand_id=mdl.brand_id,  | 
            |
| 276 | 
                + ymd=ymd[:4],  | 
            |
| 277 | 
                + )  | 
            |
| 278 | 
                + cusi.users = list(set(cusi.users + [log.user_id]))  | 
            |
| 279 | 
                + cusi.num = len(cusi.users)  | 
            |
| 280 | 
                + cusi.save()  | 
            |
| 281 | 
                +  | 
            |
| 282 | 
                + cssi, _ = ConsumeSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 283 | 
                + brand_id=mdl.brand_id,  | 
            |
| 284 | 
                + ymd=ymd,  | 
            |
| 285 | 
                + )  | 
            |
| 286 | 
                + cssi.num += 1  | 
            |
| 287 | 
                + cssi.save()  | 
            |
| 288 | 
                + cssi, _ = ConsumeSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 289 | 
                + brand_id=mdl.brand_id,  | 
            |
| 290 | 
                + ymd=ymd[:6],  | 
            |
| 291 | 
                + )  | 
            |
| 292 | 
                + cssi.num += 1  | 
            |
| 293 | 
                + cssi.save()  | 
            |
| 294 | 
                + cssi, _ = ConsumeSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 295 | 
                + brand_id=mdl.brand_id,  | 
            |
| 296 | 
                + ymd=ymd[:4],  | 
            |
| 297 | 
                + )  | 
            |
| 298 | 
                + cssi.num += 1  | 
            |
| 299 | 
                + cssi.save()  | 
            |
| 300 | 
                +  | 
            |
| 301 | 
                + # 日型号销量统计  | 
            |
| 302 | 
                + cmssi, _ = ConsumeModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 303 | 
                + brand_id=mdl.brand_id,  | 
            |
| 304 | 
                + model_name=mdl.model_uni_name,  | 
            |
| 305 | 
                + ymd=ymd,  | 
            |
| 306 | 
                + )  | 
            |
| 307 | 
                + cmssi.num += 1  | 
            |
| 308 | 
                + cmssi.save()  | 
            |
| 309 | 
                + # 月型号销量统计  | 
            |
| 310 | 
                + cmssi, _ = ConsumeModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 311 | 
                + brand_id=mdl.brand_id,  | 
            |
| 312 | 
                + model_name=mdl.model_uni_name,  | 
            |
| 313 | 
                + ymd=ymd[:6],  | 
            |
| 314 | 
                + )  | 
            |
| 315 | 
                + cmssi.num += 1  | 
            |
| 316 | 
                + cmssi.save()  | 
            |
| 317 | 
                + # 年型号销量统计  | 
            |
| 318 | 
                + cmssi, _ = ConsumeModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 319 | 
                + brand_id=mdl.brand_id,  | 
            |
| 320 | 
                + model_name=mdl.model_uni_name,  | 
            |
| 321 | 
                + ymd=ymd[:4],  | 
            |
| 322 | 
                + )  | 
            |
| 323 | 
                + cmssi.num += 1  | 
            |
| 324 | 
                + cmssi.save()  | 
            |
| 325 | 
                +  | 
            |
| 326 | 
                +            r.rpushjson(MINI_PROGRAM_GIS_LIST, {
               | 
            |
| 327 | 
                + 'brand_id': log.brand_id,  | 
            |
| 328 | 
                + 'user_id': log.user_id,  | 
            |
| 329 | 
                + 'lat': log.lat,  | 
            |
| 330 | 
                + 'lon': log.lon,  | 
            |
| 331 | 
                + 'phone': log.phone,  | 
            |
| 332 | 
                + 'ymd': tc.local_string(tc.to_local_datetime(log.created_at), format='%Y%m%d'),  | 
            |
| 333 | 
                + })  | 
            |
| 334 | 
                +  | 
            |
| 335 | 
                +  | 
            |
| 336 | 
                +def refreshs2():  | 
            |
| 337 | 
                + SaleStatisticInfo.objects.all().delete()  | 
            |
| 338 | 
                + ModelSaleStatisticInfo.objects.all().delete()  | 
            |
| 339 | 
                + DistributorSaleStatisticInfo.objects.all().delete()  | 
            |
| 340 | 
                + ProvinceSaleStatisticInfo.objects.all().delete()  | 
            |
| 341 | 
                + SaleclerkSaleStatisticInfo.objects.all().delete()  | 
            |
| 342 | 
                +  | 
            |
| 343 | 
                + logs = SaleclerkSubmitLogInfo.objects.filter(dupload=False, test_user=False, test_sn=False, status=True)  | 
            |
| 344 | 
                +  | 
            |
| 345 | 
                + for log in logs:  | 
            |
| 346 | 
                + ymd = tc.local_string(tc.to_local_datetime(log.created_at), format='%Y%m%d')  | 
            |
| 347 | 
                +  | 
            |
| 348 | 
                + try:  | 
            |
| 349 | 
                + brand = BrandInfo.objects.get(pk=log.brand_pk)  | 
            |
| 350 | 
                + except BrandInfo.DoesNotExist:  | 
            |
| 351 | 
                + continue  | 
            |
| 352 | 
                +  | 
            |
| 353 | 
                + try:  | 
            |
| 354 | 
                + model = ModelInfo.objects.get(pk=log.model_pk)  | 
            |
| 355 | 
                + except ModelInfo.DoesNotExist:  | 
            |
| 356 | 
                + continue  | 
            |
| 357 | 
                +  | 
            |
| 358 | 
                + try:  | 
            |
| 359 | 
                + clerk = SaleclerkInfo.objects.get(clerk_id=log.clerk_id, status=True)  | 
            |
| 360 | 
                + except SaleclerkInfo.DoesNotExist:  | 
            |
| 361 | 
                + continue  | 
            |
| 362 | 
                +  | 
            |
| 363 | 
                + try:  | 
            |
| 364 | 
                + distributor = DistributorInfo.objects.get(distributor_id=clerk.distributor_id)  | 
            |
| 365 | 
                + except DistributorInfo.DoesNotExist:  | 
            |
| 366 | 
                + continue  | 
            |
| 367 | 
                +  | 
            |
| 368 | 
                + with transaction.atomic():  | 
            |
| 369 | 
                + # 日销量统计  | 
            |
| 370 | 
                + ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 371 | 
                + brand_id=brand.brand_id,  | 
            |
| 372 | 
                + ymd=ymd,  | 
            |
| 373 | 
                + )  | 
            |
| 374 | 
                + ssi.num += 1  | 
            |
| 375 | 
                + ssi.save()  | 
            |
| 376 | 
                + # 月销量统计  | 
            |
| 377 | 
                + ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 378 | 
                + brand_id=brand.brand_id,  | 
            |
| 379 | 
                + ymd=ymd[:6],  | 
            |
| 380 | 
                + )  | 
            |
| 381 | 
                + ssi.num += 1  | 
            |
| 382 | 
                + ssi.save()  | 
            |
| 383 | 
                + # 年销量统计  | 
            |
| 384 | 
                + ssi, _ = SaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 385 | 
                + brand_id=brand.brand_id,  | 
            |
| 386 | 
                + ymd=ymd[:4],  | 
            |
| 387 | 
                + )  | 
            |
| 388 | 
                + ssi.num += 1  | 
            |
| 389 | 
                + ssi.save()  | 
            |
| 390 | 
                +  | 
            |
| 391 | 
                + # 型号销量统计  | 
            |
| 392 | 
                + mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 393 | 
                + brand_id=brand.brand_id,  | 
            |
| 394 | 
                + model_name=model.model_uni_name,  | 
            |
| 395 | 
                + ymd=ymd,  | 
            |
| 396 | 
                + )  | 
            |
| 397 | 
                + mssi.saleclerks += [clerk.clerk_id]  | 
            |
| 398 | 
                + mssi.num = len(mssi.saleclerks)  | 
            |
| 399 | 
                + mssi.save()  | 
            |
| 400 | 
                +  | 
            |
| 401 | 
                + mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 402 | 
                + brand_id=brand.brand_id,  | 
            |
| 403 | 
                + model_name=model.model_uni_name,  | 
            |
| 404 | 
                + ymd=ymd[:6],  | 
            |
| 405 | 
                + )  | 
            |
| 406 | 
                + mssi.saleclerks += [clerk.clerk_id]  | 
            |
| 407 | 
                + mssi.num = len(mssi.saleclerks)  | 
            |
| 408 | 
                + mssi.save()  | 
            |
| 409 | 
                +  | 
            |
| 410 | 
                + mssi, _ = ModelSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 411 | 
                + brand_id=brand.brand_id,  | 
            |
| 412 | 
                + model_name=model.model_uni_name,  | 
            |
| 413 | 
                + ymd=ymd[:4],  | 
            |
| 414 | 
                + )  | 
            |
| 415 | 
                + mssi.saleclerks += [clerk.clerk_id]  | 
            |
| 416 | 
                + mssi.num = len(mssi.saleclerks)  | 
            |
| 417 | 
                + mssi.save()  | 
            |
| 418 | 
                +  | 
            |
| 419 | 
                + # 经销商销量统计  | 
            |
| 420 | 
                + dssi, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 421 | 
                + brand_id=brand.brand_id,  | 
            |
| 422 | 
                + distributor_id=distributor.distributor_id,  | 
            |
| 423 | 
                + ymd=ymd,  | 
            |
| 424 | 
                + )  | 
            |
| 425 | 
                + dssi.distributor_name = distributor.distributor_name  | 
            |
| 426 | 
                + dssi.num += 1  | 
            |
| 427 | 
                + dssi.save()  | 
            |
| 428 | 
                +  | 
            |
| 429 | 
                + dssi2, _ = DistributorSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 430 | 
                + brand_id=brand.brand_id,  | 
            |
| 431 | 
                + distributor_id=distributor.distributor_id,  | 
            |
| 432 | 
                + ymd=0,  | 
            |
| 433 | 
                + )  | 
            |
| 434 | 
                + dssi2.distributor_name = distributor.distributor_name  | 
            |
| 435 | 
                + dssi2.num += 1  | 
            |
| 436 | 
                + dssi2.save()  | 
            |
| 437 | 
                +  | 
            |
| 438 | 
                + # 日省份销量统计  | 
            |
| 439 | 
                + pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 440 | 
                + brand_id=brand.brand_id,  | 
            |
| 441 | 
                + province_code=distributor.distributor_province_code,  | 
            |
| 442 | 
                + ymd=ymd,  | 
            |
| 443 | 
                + )  | 
            |
| 444 | 
                + pssi.province_name = distributor.distributor_province_name  | 
            |
| 445 | 
                + pssi.num += 1  | 
            |
| 446 | 
                + pssi.save()  | 
            |
| 447 | 
                + # 月省份销量统计  | 
            |
| 448 | 
                + pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 449 | 
                + brand_id=brand.brand_id,  | 
            |
| 450 | 
                + province_code=distributor.distributor_province_code,  | 
            |
| 451 | 
                + ymd=ymd[:6],  | 
            |
| 452 | 
                + )  | 
            |
| 453 | 
                + pssi.province_name = distributor.distributor_province_name  | 
            |
| 454 | 
                + pssi.num += 1  | 
            |
| 455 | 
                + pssi.save()  | 
            |
| 456 | 
                + # 年省份销量统计  | 
            |
| 457 | 
                + pssi, _ = ProvinceSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 458 | 
                + brand_id=brand.brand_id,  | 
            |
| 459 | 
                + province_code=distributor.distributor_province_code,  | 
            |
| 460 | 
                + ymd=ymd[:4],  | 
            |
| 461 | 
                + )  | 
            |
| 462 | 
                + pssi.province_name = distributor.distributor_province_name  | 
            |
| 463 | 
                + pssi.num += 1  | 
            |
| 464 | 
                + pssi.save()  | 
            |
| 465 | 
                +  | 
            |
| 466 | 
                + # 日销售员销量统计  | 
            |
| 467 | 
                + sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 468 | 
                + brand_id=brand.brand_id,  | 
            |
| 469 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 470 | 
                + ymd=ymd,  | 
            |
| 471 | 
                + )  | 
            |
| 472 | 
                + sssi.distributor_id = distributor.distributor_id  | 
            |
| 473 | 
                + sssi.distributor_name = distributor.distributor_name  | 
            |
| 474 | 
                + sssi.distributor_short_name = distributor.distributor_short_name  | 
            |
| 475 | 
                + sssi.clerk_name = clerk.clerk_name  | 
            |
| 476 | 
                + sssi.num += 1  | 
            |
| 477 | 
                + sssi.save()  | 
            |
| 478 | 
                + # 月销售员销量统计  | 
            |
| 479 | 
                + sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 480 | 
                + brand_id=brand.brand_id,  | 
            |
| 481 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 482 | 
                + ymd=ymd[:6],  | 
            |
| 483 | 
                + )  | 
            |
| 484 | 
                + sssi.distributor_id = distributor.distributor_id  | 
            |
| 485 | 
                + sssi.distributor_name = distributor.distributor_name  | 
            |
| 486 | 
                + sssi.distributor_short_name = distributor.distributor_short_name  | 
            |
| 487 | 
                + sssi.clerk_name = clerk.clerk_name  | 
            |
| 488 | 
                + sssi.num += 1  | 
            |
| 489 | 
                + sssi.save()  | 
            |
| 490 | 
                + # 年销售员销量统计  | 
            |
| 491 | 
                + sssi, _ = SaleclerkSaleStatisticInfo.objects.select_for_update().get_or_create(  | 
            |
| 492 | 
                + brand_id=brand.brand_id,  | 
            |
| 493 | 
                + clerk_id=clerk.clerk_id,  | 
            |
| 494 | 
                + ymd=ymd[:4],  | 
            |
| 495 | 
                + )  | 
            |
| 496 | 
                + sssi.distributor_id = distributor.distributor_id  | 
            |
| 497 | 
                + sssi.distributor_name = distributor.distributor_name  | 
            |
| 498 | 
                + sssi.distributor_short_name = distributor.distributor_short_name  | 
            |
| 499 | 
                + sssi.clerk_name = clerk.clerk_name  | 
            |
| 500 | 
                + sssi.num += 1  | 
            |
| 501 | 
                + sssi.save()  | 
            
                @@ -3,4 +3,5 @@ from __future__ import unicode_literals  | 
            ||
| 3 | 3 | 
                 | 
            
| 4 | 4 | 
                from django.contrib import admin  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +  | 
            |
| 6 | 7 | 
                # Register your models here.  | 
            
                @@ -3,4 +3,5 @@ from __future__ import unicode_literals  | 
            ||
| 3 | 3 | 
                 | 
            
| 4 | 4 | 
                from django.db import models  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +  | 
            |
| 6 | 7 | 
                # Create your models here.  | 
            
                @@ -3,4 +3,5 @@ from __future__ import unicode_literals  | 
            ||
| 3 | 3 | 
                 | 
            
| 4 | 4 | 
                from django.test import TestCase  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +  | 
            |
| 6 | 7 | 
                # Create your tests here.  | 
            
                @@ -0,0 +1,12 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.contrib import admin  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from staff.models import StaffDeleteClerkSaleSubmitLogInfo  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class StaffDeleteClerkSaleSubmitLogInfoAdmin(admin.ModelAdmin):  | 
            |
| 9 | 
                +    list_display = ('username', 'code', 'status', 'created_at', 'updated_at')
               | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                +admin.site.register(StaffDeleteClerkSaleSubmitLogInfo, StaffDeleteClerkSaleSubmitLogInfoAdmin)  | 
            
                @@ -0,0 +1,8 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +from __future__ import unicode_literals  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.apps import AppConfig  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class StaffConfig(AppConfig):  | 
            |
| 8 | 
                + name = 'staff'  | 
            
                @@ -0,0 +1,31 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +# Generated by Django 1.11.28 on 2020-03-01 13:19  | 
            |
| 3 | 
                +from __future__ import unicode_literals  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + initial = True  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + dependencies = [  | 
            |
| 13 | 
                + ]  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                + operations = [  | 
            |
| 16 | 
                + migrations.CreateModel(  | 
            |
| 17 | 
                + name='StaffDeleteClerkSaleSubmitLogInfo',  | 
            |
| 18 | 
                + fields=[  | 
            |
| 19 | 
                +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 20 | 
                +                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 21 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 22 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 23 | 
                +                ('username', models.CharField(blank=True, db_index=True, help_text='\u7528\u6237\u540d', max_length=32, null=True, verbose_name='username')),
               | 
            |
| 24 | 
                +                ('code', models.CharField(blank=True, db_index=True, help_text='\u673a\u8eab\u7801', max_length=32, null=True, verbose_name='code')),
               | 
            |
| 25 | 
                + ],  | 
            |
| 26 | 
                +            options={
               | 
            |
| 27 | 
                + 'verbose_name': 'staffdeleteclerksalesubmitloginfo',  | 
            |
| 28 | 
                + 'verbose_name_plural': 'staffdeleteclerksalesubmitloginfo',  | 
            |
| 29 | 
                + },  | 
            |
| 30 | 
                + ),  | 
            |
| 31 | 
                + ]  | 
            
                @@ -0,0 +1,17 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.db import models  | 
            |
| 4 | 
                +from django.utils.translation import ugettext_lazy as _  | 
            |
| 5 | 
                +from django_models_ext import BaseModelMixin  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class StaffDeleteClerkSaleSubmitLogInfo(BaseModelMixin):  | 
            |
| 9 | 
                + username = models.CharField(_(u'username'), max_length=32, blank=True, null=True, help_text=u'用户名', db_index=True)  | 
            |
| 10 | 
                + code = models.CharField(_(u'code'), max_length=32, blank=True, null=True, help_text=u'机身码', db_index=True)  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                + class Meta:  | 
            |
| 13 | 
                + verbose_name = _(u'staffdeleteclerksalesubmitloginfo')  | 
            |
| 14 | 
                + verbose_name_plural = _(u'staffdeleteclerksalesubmitloginfo')  | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                + def __unicode__(self):  | 
            |
| 17 | 
                + return unicode(self.pk)  | 
            
                @@ -0,0 +1,6 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +from __future__ import unicode_literals  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.test import TestCase  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +# Create your tests here.  | 
            
                @@ -0,0 +1,6 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +from __future__ import unicode_literals  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.shortcuts import render  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +# Create your views here.  |